home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 112 / EnigmaAmiga112CD.iso / dalla rivista / news / orbit / source / missile.c < prev    next >
C/C++ Source or Header  |  2000-05-01  |  9KB  |  441 lines

  1. /*
  2.     Amiga port by Oliver Gantert
  3.  
  4.     27.04.2000 - fixed some compiler warnings
  5. */
  6. /*
  7.  
  8. ORBIT, a freeware space combat simulator
  9. Copyright (C) 1999  Steve Belczyk <steve1@genesis.nred.ma.us>
  10.  
  11. This program is free software; you can redistribute it and/or
  12. modify it under the terms of the GNU General Public License
  13. as published by the Free Software Foundation; either version 2
  14. of the License, or (at your option) any later version.
  15.  
  16. This program is distributed in the hope that it will be useful,
  17. but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19. GNU General Public License for more details.
  20.  
  21. You should have received a copy of the GNU General Public License
  22. along with this program; if not, write to the Free Software
  23. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  24.  
  25. */
  26.  
  27. #include "orbit.h"
  28.  
  29. void InitMissiles()
  30. /*
  31.  *  Set up missile structures
  32.  */
  33. {
  34.   int i;
  35.  
  36.   /* Mark all missiles as unused */
  37.   for (i=0; i<NMSLS; i++)
  38.   {
  39.     msl[i].age = 0.0;
  40.   }
  41. }
  42.  
  43. int FindMissile()
  44. /*
  45.  *  Find unused missile
  46.  */
  47. {
  48.   int i, oldest;
  49.   double maxage;
  50.  
  51.   /* Look for free missile, or oldest */
  52.   for (i=0; i<NMSLS; i++)
  53.   {
  54.     if (msl[i].age == 0.0) return (i);
  55.  
  56.     if (i == 0)
  57.     {
  58.       maxage = msl[i].age;
  59.       oldest = i;
  60.     }
  61.     else
  62.     {
  63.       if (msl[i].age > maxage)
  64.       {
  65.         maxage = msl[i].age;
  66.         oldest = i;
  67.       }
  68.     }
  69.   }
  70.  
  71.   /* None free, return oldest */
  72.   return (oldest);
  73. }
  74.  
  75. void FireMissile (double *pos, double *vel, double *dir, int friendly, int wep, int owner)
  76. /*
  77.  *  Fire missile at the given location and velocity, in
  78.  *  the specified direction
  79.  */
  80. {
  81.   int m;
  82.   double v[3];
  83.  
  84.   /* Find a free missile */
  85.   m = FindMissile();
  86.  
  87.   /* Set it up */
  88.   msl[m].age = deltaT;
  89.   Vset (msl[m].pos, pos);
  90.  
  91.   if (friendly && !am_client && !am_server)
  92.   {
  93.     Vmul (v, player.up, -0.005);
  94.     Vadd (msl[m].pos, msl[m].pos, v);
  95.   }
  96.  
  97.   Vmul (msl[m].vel, dir, weapon[wep].speed);
  98.   Vadd (msl[m].vel, msl[m].vel, vel);
  99.  
  100.   msl[m].friendly = friendly;
  101.   msl[m].weapon = wep;
  102.   msl[m].owner = owner;
  103.  
  104.   /* Play the sound */
  105.   /* if (sound) PlaySound ("phaser.wav", NULL, SND_ASYNC | SND_FILENAME); */
  106.   if (sound) PlayAudio (SOUND_FIRE);
  107. }
  108.  
  109. void MoveMissiles()
  110. /*
  111.  *  Move all the missiles
  112.  */
  113. {
  114.   int m, t, p;
  115.   double v[3], deltav[3];
  116.  
  117.   /* Loop through missiles */
  118.   for (m=0; m<NMSLS; m++)
  119.   {
  120.     /* If missile in use */
  121.     if (msl[m].age > 0.0)
  122.     {
  123.       /* Bump age */
  124.       msl[m].age += deltaT;
  125.  
  126.       /* See if expired */
  127.       if (msl[m].age > weapon[msl[m].weapon].expire)
  128.       {
  129.         DestroyMissile (m);
  130.         return;
  131.       }
  132.  
  133.       /* See if missile has hit planet */
  134.       if ((-1) != (p = InsidePlanet (msl[m].pos)))
  135.       {
  136.         /* Missile has hit planet */
  137.  
  138.         /* Move point of impact just above planet surface */
  139.         Vsub (v, msl[m].pos, planet[p].pos);
  140.         Normalize (v);
  141.         Vmul (v, v, planet[p].radius*1.05);
  142.         Vadd (v, v, planet[p].pos);
  143.         Boom (v, weapon[msl[m].weapon].yield/100.0);
  144.         DestroyMissile (m);
  145.         return;
  146.       }
  147.  
  148.       /* See if missile hit a target */
  149.       if ((-1) != (t = HitTarget (m)))
  150.       {
  151.         /* Missle hit target */
  152.         MissileHitTarget (m, t);
  153.         return;
  154.       }
  155.  
  156.       /* See if missile hit player */
  157.       if (!msl[m].friendly && !am_client && 
  158.       (state != STATE_DEAD1) && (state != STATE_DEAD2) )
  159.       {
  160.         if (TARGDIST2 > Dist2 (msl[m].pos[0], msl[m].pos[1], msl[m].pos[2],
  161.         player.pos[0], player.pos[1], player.pos[2]))
  162.         {
  163.           /* Missile hit player */
  164.           MissileHitPlayer (m);
  165.           return;
  166.         }
  167.       }
  168.       
  169.       /* Else update its position */
  170.       if (gravity)
  171.       {
  172.         Gravity (deltav, msl[m].pos);
  173.         Vadd (msl[m].vel, msl[m].vel, deltav);
  174.       }
  175.       Vmul (v, msl[m].vel, deltaT);
  176.       Vadd (msl[m].pos, msl[m].pos, v);
  177.     }
  178.   }
  179. }
  180.  
  181. void DestroyMissile (int m)
  182. /*
  183.  *  Missile has expired 
  184.  */
  185. {
  186.   msl[m].age = 0.0;
  187. }
  188.  
  189. void DrawMissiles ()
  190. /*
  191.  *  Draw all the missiles
  192.  */
  193. {
  194.   int m;
  195.  
  196.   for (m=0; m<NMSLS; m++)
  197.   {
  198.     if (msl[m].age > 0.0) DrawMissile (m);
  199.   }
  200. }
  201.  
  202. void DrawMissile (int m)
  203. /*
  204.  *  Draw this missile
  205.  */
  206. {
  207.   glPushMatrix();
  208.   glDisable (GL_LIGHTING);
  209.   glDisable (GL_CULL_FACE);
  210.  
  211.   switch (weapon[msl[m].weapon].renderer)
  212.   {
  213.     case 0: DrawMissile0 (m);
  214.     break;
  215.  
  216.     case 1: DrawMissile1 (m);
  217.     break;
  218.  
  219.     case 2: DrawMissile2 (m);
  220.     break;
  221.  
  222.     case 3: DrawMissile3 (m);
  223.     break;
  224.  
  225.     case 4: DrawMissile4 (m);
  226.     break;
  227.   }
  228.  
  229.   glEnable (GL_CULL_FACE);
  230.   glEnable (GL_LIGHTING);
  231.   glPopMatrix();
  232. }
  233.  
  234. void DrawMissile0 (int m)
  235. {
  236.   double r, s, v[3];
  237.  
  238.   /* Figure how much to spin missile */
  239.   r = absT - ((double)(int)absT);
  240.   s = 360.0 * r;
  241.  
  242.   glColor3fv (weapon[msl[m].weapon].color);
  243.  
  244.   Vsub (v, msl[m].pos, player.pos);
  245.   glTranslated (v[0], v[1], v[2]);
  246.   glRotated (s, 0.3, 1.0, 0.6);
  247.  
  248.   glBegin (GL_LINES);
  249.   glVertex3d (-0.01, 0.0, 0.0);
  250.   glVertex3d ( 0.01, 0.0, 0.0);
  251.   glVertex3d (0.0, -0.01, 0.0);
  252.   glVertex3d (0.0,  0.01, 0.0);
  253.   glVertex3d (0.0, 0.0, -0.01);
  254.   glVertex3d (0.0, 0.0,  0.01);
  255.   glEnd();
  256. }
  257.  
  258. void DrawMissile1 (int m)
  259. {
  260.   double r, s, v[3];
  261.  
  262.   /* Figure how much to spin missile */
  263.   r = absT - ((double)(int)absT);
  264.   s = 360.0 * r;
  265.  
  266.   glColor3fv (weapon[msl[m].weapon].color);
  267.  
  268.   Vsub (v, msl[m].pos, player.pos);
  269.   glTranslated (v[0], v[1], v[2]);
  270.   glRotated (s, 0.3, 1.0, 0.6);
  271.  
  272.   glBegin (GL_LINES);
  273.   glVertex3d (-0.01, 0.0, 0.0);
  274.   glVertex3d ( 0.01, 0.0, 0.0);
  275.   glVertex3d (0.0, -0.01, 0.0);
  276.   glVertex3d (0.0,  0.01, 0.0);
  277.   glVertex3d (0.0, 0.0, -0.01);
  278.   glVertex3d (0.0, 0.0,  0.01);
  279.   glEnd();
  280. }
  281.  
  282. void DrawMissile2 (int m)
  283. {
  284.   double v1[3], v2[3], v3[3], v4[4], vel[3], v[3];
  285.  
  286.   glColor3fv (weapon[msl[m].weapon].color);
  287.  
  288.   Vsub (v, msl[m].pos, player.pos);
  289.   glTranslated (v[0], v[1], v[2]);
  290.  
  291.   Vmul (vel, msl[m].vel, 0.1);
  292.  
  293.   glBegin (GL_QUADS);
  294.  
  295.   v1[0] =  0.01; v1[1] = 0.0; v1[2] = 0.0;
  296.   v2[0] = -0.01; v2[1] = 0.0; v2[2] = 0.0;
  297.   Vsub (v3, v2, vel);
  298.   Vsub (v4, v1, vel);
  299.   glVertex3dv (v1);
  300.   glVertex3dv (v2);
  301.   glVertex3dv (v3);
  302.   glVertex3dv (v4);
  303.  
  304.   v1[0] = 0.0; v1[1] =  0.01; v1[2] = 0.0;
  305.   v2[0] = 0.0; v2[1] = -0.01; v2[2] = 0.0;
  306.   Vsub (v3, v2, vel);
  307.   Vsub (v4, v1, vel);
  308.   glVertex3dv (v1);
  309.   glVertex3dv (v2);
  310.   glVertex3dv (v3);
  311.   glVertex3dv (v4);
  312.  
  313.   v1[0] = 0.0; v1[1] = 0.0; v1[2] =  0.01;
  314.   v2[0] = 0.0; v2[1] = 0.0; v2[2] = -0.01;
  315.   Vsub (v3, v2, vel);
  316.   Vsub (v4, v1, vel);
  317.   glVertex3dv (v1);
  318.   glVertex3dv (v2);
  319.   glVertex3dv (v3);
  320.   glVertex3dv (v4);
  321.  
  322.   glEnd();
  323. }
  324.  
  325. void DrawMissile3 (int m)
  326. {
  327.   double r, s, v[3];
  328.  
  329.   /* Figure how much to spin missile */
  330.   r = absT - ((double)(int)absT);
  331.   s = 360.0 * r;
  332.  
  333.   glColor3fv (weapon[msl[m].weapon].color);
  334.  
  335.   Vsub (v, msl[m].pos, player.pos);
  336.   glTranslated (v[0], v[1], v[2]);
  337.   glRotated (s, 0.3, 1.0, 0.6);
  338.   glScaled (0.01, 0.01, 0.01);
  339.  
  340.   glutSolidTetrahedron ();
  341. }
  342.  
  343. void DrawMissile4 (int m)
  344. {
  345.   int i;
  346.   double v[3], u[3];
  347.  
  348.   glColor3fv (weapon[msl[m].weapon].color);
  349.  
  350.   Vsub (u, msl[m].pos, player.pos);
  351.   glTranslated (u[0], u[1], u[2]);
  352.  
  353.   glBegin (GL_LINE_LOOP);
  354.   for (i=0; i<6; i++)
  355.   {
  356.     v[0] = rnd(0.04) - 0.01;
  357.     v[1] = rnd(0.04) - 0.01;
  358.     v[2] = rnd(0.04) - 0.01;
  359.     glVertex3dv (v);
  360.   }
  361.   glEnd();
  362. }
  363.  
  364. void MissileHitPlayer (int m)
  365. /*
  366.  *  Missile m hit player.  Ouch!
  367.  */
  368. {
  369.   /* Flash screen red */
  370.   palette_flash = 2;
  371.  
  372.   /* Damage shields */
  373.   player.shields -= weapon[msl[m].weapon].yield;
  374.  
  375.   /* Get rid of missile */
  376.   DestroyMissile (m);
  377.  
  378.   /* See if player died */
  379.   if (vulnerable && (player.shields < 0.0) && !am_client)
  380.   {
  381.     if (am_server) 
  382.     {
  383.       /* Tell other clients */ 
  384.       NetDestroyClient (server.client, FindClientByTarget (msl[m].owner)); 
  385.       NetPlayerDies(); 
  386.     }
  387.     else 
  388.     {
  389.       /* Single player games, reset */
  390.       InitPlayer();
  391.       ReadMission (mission.fn);
  392.       Mprint ("You were killed!  Restarting mission."); 
  393.     }
  394.   }
  395.  
  396.   if (player.shields < 0.0) player.shields = 100.0;
  397. }
  398.  
  399. void MissileHitTarget (int m, int t)
  400. /*
  401.  *  Missile m hit target t.  Go get 'em!
  402.  */
  403. {
  404.   int e;
  405.  
  406.   Boom (msl[m].pos, weapon[msl[m].weapon].yield/100.0);
  407.  
  408.   target[t].shields -= weapon[msl[m].weapon].yield;
  409.   if (target[t].shields < 0.0) target[t].shields = 0.0;
  410.  
  411.   /* Announce to network */
  412.   if (am_server) NetHitTarget (t, m);
  413.  
  414.   /* See if we set off an event */
  415.   for (e=0; e<NEVENTS; e++)
  416.   {
  417.     if (event[e].pending &&
  418.     event[e].enabled &&
  419.     (event[e].trigger == EVENT_SHIELDS) &&
  420.     (!strcasecmp (event[e].cvalue, target[t].name)) &&
  421.     (target[t].shields <= event[e].fvalue) )
  422.     {
  423.       EventAction (e);
  424.     }
  425.   }
  426.  
  427.   /* See if target is destroyed */
  428.   if (!am_client && target[t].shields <= 0.0)
  429.   {
  430.     /* Announce to network */
  431.     NetDestroyTarget (t, m);
  432.  
  433.     /* Kablooie! */
  434.     Boom (target[t].pos, 1.0);
  435.     if (!am_server) DestroyTarget (t);
  436.     if (am_server) target[t].shields = 100.0;
  437.   }
  438.  
  439.   DestroyMissile (m);
  440. }
  441.